代码组织和部署
模块的路径解析规则
require支持/或者盘符的绝对路径,也支持./开头的相对地址
同时require也支持第三种写法
内置模块
如果传递给require的函数是node.js的内置模块,将会不做路径解析,直接返回内部exports模块要导出的对象
node_modules目录
node.js定义一个node_modules存放模块,每次使用foo/bar的方式的时候,会先寻找该目录下的node_modules,接着上一层,知道顶层为止
NODE_PATH环境变量
如果设置变量,将会按照变量的地址进行寻找
包
包是由多个子模块组成的大模块为包,其中所有的子模块都放进同一个目录里
index.js
当模块文件名为index.js的时候,加载模块所在目录的路径代替模块文件路径
package.json
package.json能自定义入口模块的路径、
-/home/user/lib
`cat/
+ doc/
- lib/
head.js
body.js
main.js
+ tests/
package.json
以上为一个目录文件
配置文件内容如下
{
"name": "cat";
"main": "./lib/main.js";
}
其中定义该包的名称为cat,入口文件为相对路径下的main.js
即,加载该模块的时候路径为
/home/user/lib/cat
node.js会自动根据配置文件找到入口模块所在的位置
命令行程序
为了在任何目录实现
node-echo hello word
windows
需要cmd文件,
需要先将其目录添加到环境变量
在该目录下创建cmd文件
创建cmd文件的目的是能链接执行一个js文件
@node "C:\User\user\bin\node-echo.js" %*
这样就完成了在任何目录下使用
node-echo
命令
工程目录
- /hoem/user/workspace/node-echo/ # 工程目录
- bin # 存放命令行相关代码
node-echo.js
+ doc/ # 存放相关文档
- lib/ # 存放api相关代码
cho.js
- node_modules/ # 存放第三方包
+ argv/
+ tests/ # 存放测试用例
package.json # 元数据文件
README.md # 说明文件
文件内容
/*bin/node-echo*/
var argv = require("argv"),
echo = require('../lib/echo');
console.log(echo(argv.join("")));
/*lib/echo.js*/
module.exports = function (message) {
return message;
};
/*package.json*/
{
"name": "node-echo",
"main": "./lib/echo.js",
}
npm
使用npm
require("argv");
因为第三行包在node_modules文件夹下,所以直接加上名称即可使用
包依赖声明
{
"name": "node-echo",
"main": "./lib/echo.js",
"dependencies": {
"argv": "0.0.2",
},
};
声明该报依赖argv包的0.0.2版本
下载包时候
直接
npm-install
即可批量安装声明的依赖包
当他人下载的时候,也会自动下载进一步的依赖的第三方包
目录结构如下
- project/
- node_modules/
- node-echo/
- node-modules/
+ argv/
这样就完成了包的问题
安装命令行程序
~ %APPDATA%\npm\ # 在windows系统下
- node_modules\
+ node-echo\
node-echo.cmd
版本号
x,y,z
修复bug时,需要更新z位
增加新功能,并且向下兼容,更新到y为
大变动,不兼容,更新到x位
一些比较有用的npm
npm cache clear # 清空npm本地缓存
npm update -g # 将全局安装的包更新到最新版
小结
写代码前,目录结构规划后
稍微大的程序,使用模块化管理
文件操作
首先
提供了一些文件操作的api
小文件拷贝
var fs = require("fs");
var data = fs.readFileSync('input.txt');
data = "sdferg" + data.toString();
for(var i = 0; i <= 10; i++){
data = data + data;
}
fs.writeFileSync('put.txt', data);
console.log(data);
console.log("程序执行结束!");
将其保存进内存中,进行操作
随带着解释一下第一句,第一句中的是将其fs模块读取,并保存进入fs对象中
大文件拷贝
如果文件过大,这样保存进入内存拷贝会导致内存溢出,所以一点一点读,边读边写
var fs = require("fs");
var txt = fs.createReadStream("input.txt"); // 创建了一个只读数据流
var writeTxt = fs.createWriteStream("out.txt"); //创建了一个写的数据流
txt.pipe(writeTxt);
创建两个流,将其连接,完成文件的读写
一些大致的api
数据块
buffer对二进制数据的操作
类似于C中的指针
slice方法类似C中的对于指针的移动
数据流
stream基于事件工作,这是需要注意的
使用数据流的问题在于会产生读完以后无法处理的情况,通过回调函数,达到通知以后在让生产者进行处理,即消费者每消费一件,生产者进行生产
ps: 回调目前看不懂,异步在下一节中有
这一点过
遍历目录
当要找到并处理制定目录下的所有js文件的时候,需要遍历整个目录
递归算法
遍历目录采用的是递归算法
遍历算法
目录为树状结构,遍历采用深度优先+先序的算法进行遍历吗,到达节点以后,首先接着遍历子节点,而不是邻居节点,
举例
A
/ \
B C
/ \ \
D E F
上方的树,先A > B > D > E > C > F
ps。。我需要数据结构。。有必要折腾一本js的数据结构和算法
同步遍历
先遇到目录,然后接着遇到文件,当遇到文件的时候,暂停遍历,将结果通过回调函数给主程序进行判断,接着判断结果返回,根据判断的结果继续进行遍历
异步遍历
和同步变量完全相同,不过,是边遍历边进行返回,同时主程序也在运行
文本编码
常用的一个是万国码的存储方式utf-8,一个是gbk
bom的问题
bom会标记文件的一些相关信息,下面是一个使用函数,将其bom移出
function readText(pathname) {
var bin = fs.readFileSync(pathname); // 创建一个流 创建一个读取文件的数据流
if (bin[0] === 0xEF && bin[1] === 0xBB %% bin[2] === 0xBF) {
bin = bin.slice(3); // 去除bom
}
return bin.toString('utf-8') // 以utf-8的格式进行返回
};
GBK转utf-8
GBk某种原因,不在支持范围内部,所以,如果读取,需要将其转换为utf-8
使用这个包iconv-lite进行转换,先使用npm进行下载,完后进行读取,下面编写一个函数进行读取
var iconv = require('iconv-lite'); // 加载相关模块
function readGBKText(pathname) {
var bin = fs.readFileSync(pathname); // 创建文件流
return iconv.decode(bin, 'gbk'); // 使用iconv模块的decode方法,对bin进行转换
}
单字节编码
因为英文字母没有问题,全是ASCII进行编码和存储的,由于gbk和utf-8的问题的导致,所以呢,储存汉字的二进制依旧不变即可,只变英文字母
小结
path模块进行路径的拼接
fs模块的同步更好用,异步真的能让人崩溃
目录遍历和文件编码的处理
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。